package values

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"time"
)

// ToUint 转换目标为 Uint, 如果转换失败, 则返回0
func ToUint(v any) uint {
	if v == nil {
		return 0
	}
	to, _ := ToUintE(v)
	return to
}

// ToUintD 转换目标为 Uint, 如果转换失败, 则返回defaultVal指定的默认值
func ToUintD(v any, defaultVal uint) uint {
	if v == nil {
		return defaultVal
	}
	if to, err := ToUintE(v); err == nil {
		return to
	}
	return defaultVal
}

// ToUintE  转换目标为 Uint, 如果转换失败, 则返回0和错误信息
func ToUintE(v any) (uint, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToUintE: unable to nil to uint")
	}
	switch vs := v.(type) {
	case uint:
		return vs, nil
	case uint64:
		if vs <= math.MaxUint {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type uint64 to uint, value out of range", v)
	case uint32:
		return uint(vs), nil
	case uint16:
		return uint(vs), nil
	case uint8:
		return uint(vs), nil
	case int:
		if vs >= 0 {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type int to uint, negative value", v)
	case int64:
		if vs >= 0 {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type int64 to uint, negative value", v)
	case int32:
		if vs >= 0 {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type int32 to uint, negative value", v)
	case int16:
		if vs >= 0 {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type int16 to uint, negative value", v)
	case int8:
		if vs >= 0 {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type int8 to uint, negative value", v)
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToUintE: unable to %v of type float64 to uint, value out of range", v)
		}
		// 是否负值
		if vs < 0 {
			return 0, fmt.Errorf("ToUintE: unable to %v of type float64 to uint, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxUint 区间
		if vs <= math.MaxUint {
			return uint(vs), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type float64 to uint, value out of range", v)
	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToUintE: unable to %v of type float32 to uint, value out of range", v)
		}
		// 是否负值
		if vs64 < 0 {
			return 0, fmt.Errorf("ToUintE: unable to %v of type float32 to uint, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxUint 区间
		if vs64 <= math.MaxUint {
			return uint(vs64), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of type float32 to uint, value out of range", v)
	case string:
		return StringToUintE(vs)
	case json.Number:
		return StringToUintE(string(vs))
	case time.Weekday:
		return uint(vs), nil
	case time.Month:
		return uint(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerUint:
		return vs.Uint(), nil
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxUint {
			return uint(vss), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of interface Uint64() to uint, value out of range", v)
	case providerUint32:
		return uint(vs.Uint32()), nil
	case providerUint16:
		return uint(vs.Uint16()), nil
	case providerUint8:
		return uint(vs.Uint8()), nil
	case providerInt:
		vss := vs.Int()
		if vss >= 0 {
			return uint(vss), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of interface Int() to uint, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= 0 {
			return uint(vss), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of interface Int64() to uint, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= 0 {
			return uint(vss), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of interface Int32() to uint, value out of range", v)
	case providerInt16:
		vss := vs.Int16()
		if vss >= 0 {
			return uint(vss), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of interface Int16() to uint, value out of range", v)
	case providerInt8:
		vss := vs.Int8()
		if vss >= 0 {
			return uint(vss), nil
		}
		return 0, fmt.Errorf("ToUintE: unable to %v of interface Int8() to uint, value out of range", v)
	case providerFloat:
		vss, err := ToUintE(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToUintE: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToUintE(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToUintE: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToUintE(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToUintE: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToUintE: unable to %#v of type %T to uint", v, v)
	}
}

// ToUint64 转换目标为 Uint64, 如果转换失败, 则返回0
func ToUint64(v any) uint64 {
	if v == nil {
		return 0
	}
	to, _ := ToUint64E(v)
	return to
}

// ToUint64D 转换目标为 Uint64, 如果转换失败, 则返回defaultVal指定的默认值
func ToUint64D(v any, defaultVal uint64) uint64 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToUint64E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToUint64E  转换目标为 Uint64, 如果转换失败, 则返回0和错误信息
func ToUint64E(v any) (uint64, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToUint64E: unable to nil to uint64")
	}
	switch vs := v.(type) {
	case uint:
		return uint64(vs), nil
	case uint64:
		return vs, nil
	case uint32:
		return uint64(vs), nil
	case uint16:
		return uint64(vs), nil
	case uint8:
		return uint64(vs), nil
	case int:
		if vs >= 0 {
			return uint64(vs), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type int to uint64, negative value", v)
	case int64:
		if vs >= 0 {
			return uint64(vs), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type int64 to uint64, negative value", v)
	case int32:
		if vs >= 0 {
			return uint64(vs), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type int32 to uint64, negative value", v)
	case int16:
		if vs >= 0 {
			return uint64(vs), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type int16 to uint64, negative value", v)
	case int8:
		if vs >= 0 {
			return uint64(vs), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type int8 to uint64, negative value", v)
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToUint64E: unable to %v of type float64 to uint64, value out of range", v)
		}
		// 是否负值
		if vs < 0 {
			return 0, fmt.Errorf("ToUint64E: unable to %v of type float64 to uint64, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxUint 区间
		if vs <= math.MaxUint64 {
			return uint64(vs), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type float64 to uint64, value out of range", v)
	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToUint64E: unable to %v of type float32 to uint64, value out of range", v)
		}
		// 是否负值
		if vs64 < 0 {
			return 0, fmt.Errorf("ToUint64E: unable to %v of type float32 to uint64, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxUint 区间
		if vs64 <= math.MaxUint64 {
			return uint64(vs64), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of type float32 to uint64, value out of range", v)
	case string:
		return StringToUint64E(vs)
	case json.Number:
		return StringToUint64E(string(vs))
	case time.Weekday:
		return uint64(vs), nil
	case time.Month:
		return uint64(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerUint:
		return uint64(vs.Uint()), nil
	case providerUint64:
		return vs.Uint64(), nil
	case providerUint32:
		return uint64(vs.Uint32()), nil
	case providerUint16:
		return uint64(vs.Uint16()), nil
	case providerUint8:
		return uint64(vs.Uint8()), nil
	case providerInt:
		vss := vs.Int()
		if vss >= 0 {
			return uint64(vss), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of interface Int() to uint64, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= 0 {
			return uint64(vss), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of interface Int64() to uint64, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= 0 {
			return uint64(vss), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of interface Int32() to uint64, value out of range", v)
	case providerInt16:
		vss := vs.Int16()
		if vss >= 0 {
			return uint64(vss), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of interface Int16() to uint64, value out of range", v)
	case providerInt8:
		vss := vs.Int8()
		if vss >= 0 {
			return uint64(vss), nil
		}
		return 0, fmt.Errorf("ToUint64E: unable to %v of interface Int8() to uint64, value out of range", v)
	case providerFloat:
		vss, err := ToUint64E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToUint64E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToUint64E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToUint64E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToUint64E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToUint64E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToUint64E: unable to %#v of type %T to uint64", v, v)
	}
}

// ToUint32 转换目标为 Uint32, 如果转换失败, 则返回0
func ToUint32(v any) uint32 {
	if v == nil {
		return 0
	}
	to, _ := ToUint32E(v)
	return to
}

// ToUint32D 转换目标为 Uint32, 如果转换失败, 则返回defaultVal指定的默认值
func ToUint32D(v any, defaultVal uint32) uint32 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToUint32E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToUint32E  转换目标为 Uint32, 如果转换失败, 则返回0和错误信息
func ToUint32E(v any) (uint32, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToUint32E: unable to nil to uint32")
	}
	switch vs := v.(type) {
	case uint:
		if vs <= math.MaxUint32 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type uint to uint32, value out of range", v)
	case uint64:
		if vs <= math.MaxUint32 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type uint64 to uint32, value out of range", v)
	case uint32:
		return vs, nil
	case uint16:
		return uint32(vs), nil
	case uint8:
		return uint32(vs), nil
	case int:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint32E: unable to %v of type int to uint32, negative value", v)
		}
		if vs <= math.MaxUint32 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type int64 to uint32, value out of range", v)
	case int64:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint32E: unable to %v of type int64 to uint32, negative value", v)
		}
		if vs <= math.MaxUint32 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type int64 to uint32, value out of range", v)
	case int32:
		if vs >= 0 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type int32 to uint32, negative value", v)
	case int16:
		if vs >= 0 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type int16 to uint32, negative value", v)
	case int8:
		if vs >= 0 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type int8 to uint32, negative value", v)
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToUint32E: unable to %v of type float64 to uint32, value out of range", v)
		}
		// 是否负值
		if vs < 0 {
			return 0, fmt.Errorf("ToUint32E: unable to %v of type float64 to uint32, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxUint 区间
		if vs <= math.MaxUint32 {
			return uint32(vs), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type float64 to uint32, value out of range", v)
	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToUint32E: unable to %v of type float32 to uint32, value out of range", v)
		}
		// 是否负值
		if vs64 < 0 {
			return 0, fmt.Errorf("ToUint32E: unable to %v of type float32 to uint32, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxUint 区间
		if vs64 <= math.MaxUint32 {
			return uint32(vs64), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of type float32 to uint32, value out of range", v)
	case string:
		return StringToUint32E(vs)
	case json.Number:
		return StringToUint32E(string(vs))
	case time.Weekday:
		return uint32(vs), nil
	case time.Month:
		return uint32(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxUint32 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Uint() to uint32, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxUint32 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Uint64() to uint32, value out of range", v)
	case providerUint32:
		return vs.Uint32(), nil
	case providerUint16:
		return uint32(vs.Uint16()), nil
	case providerUint8:
		return uint32(vs.Uint8()), nil
	case providerInt:
		vss := vs.Int()
		if vss >= 0 && vss <= math.MaxUint32 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Int() to uint32, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= 0 && vss <= math.MaxUint32 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Int64() to uint32, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= 0 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Int32() to uint32, value out of range", v)
	case providerInt16:
		vss := vs.Int16()
		if vss >= 0 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Int16() to uint32, value out of range", v)
	case providerInt8:
		vss := vs.Int8()
		if vss >= 0 {
			return uint32(vss), nil
		}
		return 0, fmt.Errorf("ToUint32E: unable to %v of interface Int8() to uint32, value out of range", v)
	case providerFloat:
		vss, err := ToUint32E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToUint32E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToUint32E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToUint32E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToUint32E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToUint32E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToUint32E: unable to %#v of type %T to uint32", v, v)
	}
}

// ToUint16 转换目标为 Uint16, 如果转换失败, 则返回0
func ToUint16(v any) uint16 {
	if v == nil {
		return 0
	}
	to, _ := ToUint16E(v)
	return to
}

// ToUint16D 转换目标为 Uint16, 如果转换失败, 则返回defaultVal指定的默认值
func ToUint16D(v any, defaultVal uint16) uint16 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToUint16E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToUint16E  转换目标为 Uint16, 如果转换失败, 则返回0和错误信息
func ToUint16E(v any) (uint16, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToUint16E: unable to nil to uint16")
	}
	switch vs := v.(type) {
	case uint:
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type uint to uint16, value out of range", v)
	case uint64:
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type uint64 to uint16, value out of range", v)
	case uint32:
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type uint32 to uint16, value out of range", v)
	case uint16:
		return vs, nil
	case uint8:
		return uint16(vs), nil
	case int:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type int to uint16, negative value", v)
		}
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type int64 to uint16, value out of range", v)
	case int64:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type int64 to uint16, negative value", v)
		}
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type int64 to uint16, value out of range", v)
	case int32:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type int32 to uint16, negative value", v)
		}
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type int32 to uint16, negative value", v)
	case int16:
		if vs >= 0 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type int16 to uint16, negative value", v)
	case int8:
		if vs >= 0 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type int8 to uint16, negative value", v)
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type float64 to uint16, value out of range", v)
		}
		// 是否负值
		if vs < 0 {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type float64 to uint16, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxUint 区间
		if vs <= math.MaxUint16 {
			return uint16(vs), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type float64 to uint16, value out of range", v)
	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type float32 to uint16, value out of range", v)
		}
		// 是否负值
		if vs64 < 0 {
			return 0, fmt.Errorf("ToUint16E: unable to %v of type float32 to uint16, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxUint 区间
		if vs64 <= math.MaxUint16 {
			return uint16(vs64), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of type float32 to uint16, value out of range", v)
	case string:
		return StringToUint16E(vs)
	case json.Number:
		return StringToUint16E(string(vs))
	case time.Weekday:
		return uint16(vs), nil
	case time.Month:
		return uint16(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxUint16 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Uint() to uint16, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxUint16 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Uint64() to uint16, value out of range", v)
	case providerUint32:
		vss := vs.Uint32()
		if vss <= math.MaxUint16 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Uint32() to uint16, value out of range", v)
	case providerUint16:
		return vs.Uint16(), nil
	case providerUint8:
		return uint16(vs.Uint8()), nil
	case providerInt:
		vss := vs.Int()
		if vss >= 0 && vss <= math.MaxUint16 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Int() to uint16, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= 0 && vss <= math.MaxUint16 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Int64() to uint16, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= 0 && vss <= math.MaxUint16 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Int64() to uint16, value out of range", v)
	case providerInt16:
		vss := vs.Int16()
		if vss >= 0 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Int16() to uint16, value out of range", v)
	case providerInt8:
		vss := vs.Int8()
		if vss >= 0 {
			return uint16(vss), nil
		}
		return 0, fmt.Errorf("ToUint16E: unable to %v of interface Int8() to uint16, value out of range", v)
	case providerFloat:
		vss, err := ToUint16E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToUint16E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToUint16E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToUint16E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToUint16E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToUint16E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToUint16E: unable to %#v of type %T to uint16", v, v)
	}
}

// ToUint8 转换目标为 Uint8, 如果转换失败, 则返回0
func ToUint8(v any) uint8 {
	if v == nil {
		return 0
	}
	to, _ := ToUint8E(v)
	return to
}

// ToUint8D 转换目标为 Uint8, 如果转换失败, 则返回defaultVal指定的默认值
func ToUint8D(v any, defaultVal uint8) uint8 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToUint8E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToUint8E  转换目标为 Uint8, 如果转换失败, 则返回0和错误信息
func ToUint8E(v any) (uint8, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToUint8E: unable to nil to uint8")
	}
	switch vs := v.(type) {
	case uint:
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type uint to uint8, value out of range", v)
	case uint64:
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type uint64 to uint8, value out of range", v)
	case uint32:
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type uint32 to uint8, value out of range", v)
	case uint16:
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type uint16 to uint8, value out of range", v)
	case uint8:
		return vs, nil
	case int:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type int to uint8, negative value", v)
		}
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type int64 to uint8, value out of range", v)
	case int64:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type int64 to uint8, negative value", v)
		}
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type int64 to uint8, value out of range", v)
	case int32:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type int32 to uint8, negative value", v)
		}
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type int32 to uint8, negative value", v)
	case int16:
		if vs < 0 {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type int16 to uint8, negative value", v)
		}
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type int16 to uint8, negative value", v)
	case int8:
		if vs >= 0 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type int8 to uint8, negative value", v)
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type float64 to uint8, value out of range", v)
		}
		// 是否负值
		if vs < 0 {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type float64 to uint8, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxUint 区间
		if vs <= math.MaxUint8 {
			return uint8(vs), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type float64 to uint8, value out of range", v)
	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type float32 to uint8, value out of range", v)
		}
		// 是否负值
		if vs64 < 0 {
			return 0, fmt.Errorf("ToUint8E: unable to %v of type float32 to uint8, negative value", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxUint 区间
		if vs64 <= math.MaxUint8 {
			return uint8(vs64), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of type float32 to uint8, value out of range", v)
	case string:
		return StringToUint8E(vs)
	case json.Number:
		return StringToUint8E(string(vs))
	case time.Weekday:
		return uint8(vs), nil
	case time.Month:
		return uint8(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Uint() to uint8, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Uint64() to uint8, value out of range", v)
	case providerUint32:
		vss := vs.Uint32()
		if vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Uint32() to uint8, value out of range", v)
	case providerUint16:
		vss := vs.Uint16()
		if vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Uint16() to uint8, value out of range", v)
	case providerUint8:
		return vs.Uint8(), nil
	case providerInt:
		vss := vs.Int()
		if vss >= 0 && vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Int() to uint8, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= 0 && vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Int64() to uint8, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= 0 && vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Int64() to uint8, value out of range", v)
	case providerInt16:
		vss := vs.Int16()
		if vss >= 0 && vss <= math.MaxUint8 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Int16() to uint8, value out of range", v)
	case providerInt8:
		vss := vs.Int8()
		if vss >= 0 {
			return uint8(vss), nil
		}
		return 0, fmt.Errorf("ToUint8E: unable to %v of interface Int8() to uint8, value out of range", v)
	case providerFloat:
		vss, err := ToUint8E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToUint8E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToUint8E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToUint8E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToUint8E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToUint8E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToUint8E: unable to %#v of type %T to uint8", v, v)
	}
}
